package org.breathe.dynamic.thread.pool.starter.common.autoconfigure;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import org.breathe.dynamic.thread.pool.core.ai.BreatheDtpAiHelper;
import org.breathe.dynamic.thread.pool.core.ai.assistant.Assistant;
import org.breathe.dynamic.thread.pool.core.executor.ThreadPoolExecutorRegistry;
import org.breathe.dynamic.thread.pool.core.monitor.BreatheDtpMonitor;
import org.breathe.dynamic.thread.pool.core.monitor.endpoint.BreatheDtpEndpoint;
import org.breathe.dynamic.thread.pool.core.spring.BreatheDTPBannerPrinter;
import org.breathe.dynamic.thread.pool.core.spring.BreatheDtpPostProcessor;
import org.breathe.thread.pool.common.constant.BreatheDtpConstant;
import org.breathe.thread.pool.common.entity.AiProperties;
import org.breathe.thread.pool.common.entity.BreatheDtpProperties;
import org.breathe.thread.pool.common.utils.ApplicationContextHolder;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.info.BuildProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 基本bean自动配置
 * @author: breathe
 * @createTime: 2025-04-14
 */
@Configuration
@EnableConfigurationProperties(BreatheDtpProperties.class)
@ConditionalOnProperty(name = BreatheDtpConstant.DTP_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
public class BaseBeanAutoConfiguration {

    /**
     * 应用程序上下文
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public ApplicationContextHolder breatheDtpApplicationContextHolder() {
        return new ApplicationContextHolder();
    }

    /**
     * banner打印
     *
     * @param breatheDtpProperties 项目配置
     * @return
     */
    @Bean
    @ConditionalOnClass(BuildProperties.class)
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = BreatheDtpConstant.BANNER_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public BreatheDTPBannerPrinter breatheDTPBannerPrinter(BreatheDtpProperties breatheDtpProperties) {
        return new BreatheDTPBannerPrinter(breatheDtpProperties, BreatheDtpConstant.VERSION);
    }

    /**
     * 线程池后置处理器
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass(ApplicationContextHolder.class)
    public BreatheDtpPostProcessor breatheDtpPostProcessor() {
        return new BreatheDtpPostProcessor();
    }

    /**
     * 线程池注册类
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public ThreadPoolExecutorRegistry threadPoolExecutorRegistry() {
        return new ThreadPoolExecutorRegistry();
    }

    // 监控相关的
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = BreatheDtpConstant.MONITOR_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public BreatheDtpMonitor dtpMonitor() {
        return new BreatheDtpMonitor();
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnAvailableEndpoint
    @ConditionalOnProperty(name = BreatheDtpConstant.MONITOR_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public BreatheDtpEndpoint dtpEndpoint() {
        return new BreatheDtpEndpoint();
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = BreatheDtpConstant.AI_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public OpenAiChatModel chatModel(BreatheDtpProperties breatheDtpProperties) {
        AiProperties ai = breatheDtpProperties.getAi();
        return OpenAiChatModel.builder()
                .baseUrl(ai.getBaseUrl())
                .modelName(ai.getModelName())
                .apiKey(ai.getApiKey())
                .strictTools(true)
                .logRequests(breatheDtpProperties.getAi().getEnabledRequestLog())
                .logResponses(breatheDtpProperties.getAi().getEnabledResponseLog())
                .build();
    }

    @Bean
    @ConditionalOnClass(OpenAiChatModel.class)
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = BreatheDtpConstant.AI_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public BreatheDtpAiHelper breatheDtpAiHelper() {
        return new BreatheDtpAiHelper();
    }

    @Bean
    @ConditionalOnClass(OpenAiChatModel.class)
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = BreatheDtpConstant.AI_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public Assistant dtpAssistant(OpenAiChatModel model) {
        return AiServices.builder(Assistant.class)
                .chatModel(model)
                .chatMemory(MessageWindowChatMemory.withMaxMessages(1000))
                .build();
    }
}